<script setup>
import {
  computed,
  defineProps,
  ref,
  toRefs,
  toRaw,
  inject,
  provide,
  reactive,
  defineExpose,
  defineEmits,
  watchEffect,
  onMounted, watch,
} from "vue";
import HilightedSentence from "@/components/HilightedSentence.vue";
import FormCheckGroups from "@/components/FormCheckGroups.vue";
import {clearAndPushAll, keepIndentifiedSwapIn, replaceWith} from "@/utils/ArrayUtil";
import {
  formsOutCssMapping,
  lijuContextEventProcessors,
  phraseOWordPickInputEventProvides
} from "@/components/constants";
import PickedDoneFormCountTag from "@/components/WordFormedTag/PickedDoneFormCountTag.vue";
import {difference, orderBy, remove, sortedIndexBy} from "lodash-unified";
import FormsCountTempPickTag from "@/components/WordFormedTag/FormsCountTempPickTag.vue";
import {
  BatchOperType,
  globalContextDataKey1,
  globalContextSw,
  globalShortCutKeysEventCenter
} from "@/constants/gConstants";
import {Check, Plus, Edit, Expand, Fold} from "@element-plus/icons-vue";
import {lijuContextSW} from "@/components/constants";
import FormsCountBtn from "@/components/FormsCountBtn.vue";
import BatchOverWritingTags from "@/components/WordFormedTag/BatchOverWritingTags.vue";
import PhraseOWordPickMarkingSingleEntryView from "@/components/PhraseItComp/PhraseOWordPickMarkingSingleEntryView.vue";
import PhraseOWordUsage from "@/models/PhraseOWordUsage";
import PhraseTag from "@/components/PhraseItComp/PhraseTag.vue";
import PhraseOWordSettledSingleEntryView from "@/components/PhraseItComp/PhraseOWordSettledSingleEntryView.vue";

import {v4 as uuidv4} from "uuid";

const theProps = defineProps(["theLijuEntry", "maskNotMatched", "formsCountMap", "batchFormsCntPickSw", "batchIndividual", "batchOperType", "allDetailing"]);

const mouseInCurr = ref(false);
const pickedDoneClosableSw = ref(false);
const individualFormsCountPickSw = ref(false);
const phrasingIt = ref(false);
const expandingPhrasesAndWordsTags = ref(false);

watchEffect(() => {
  // console.log("theProps.allDetailing",theProps.allDetailing);
  expandingPhrasesAndWordsTags.value = theProps.allDetailing;
})
provide(lijuContextSW, {
  individualFormsCountPickSw,
  phrasingIt,
  expandingPhrasesAndWordsTags,
});

provide(lijuContextEventProcessors, {
  wordFormsCountsSelectDoneThen
});


provide(phraseOWordPickInputEventProvides, {
  endPhraseOWordIputPicking
});

const globelSw = inject(globalContextSw, undefined);
let globalContextKey1Data = inject(globalContextDataKey1, undefined);

function focusInFunc(e) {
  mouseInCurr.value = true;
  // console.info("focus in : ",theProps.theLijuEntry);
}

function focusOutFunc(e) {
  mouseInCurr.value = false;
  pickedDoneClosableSw.value = false;
  // phrasingIt.value=false
  // individualFormsCountPickSw.value = false;//离开是否关闭选择？

  // console.info("focus out : ",theProps.theLijuEntry);
}

// console.log('init HiliLiju',theProps.theLijuEntry)

function currLijuFormCountsPickDoneFunc(formsCountCheckedListMap) {
  // console.log('aaaa',pickedDoneFormCountsArr);

  [...formsCountCheckedListMap.keys()].forEach(form => {
    let checkedList = orderBy([...toRaw(formsCountCheckedListMap.get(form))], [], ['asc']);
    if (checkedList && checkedList.length > 0) {
      let existPickDoneFormsCountCheckedList = theProps.theLijuEntry.pickDoneFormsCountCheckedListMap.get(form);
      if (existPickDoneFormsCountCheckedList) {
        clearAndPushAll(existPickDoneFormsCountCheckedList, checkedList);
      } else {
        theProps.theLijuEntry.pickDoneFormsCountCheckedListMap.set(form, checkedList)
      }
    }
  })
}

let cmptPickDoneFormsCountArr = computed(() => {

  function orderResultArrByFormsCountMap(resultArr) {
    return orderBy(resultArr,
        pickDoneFormCount => {
          let formPartIndex = [...theProps.formsCountMap.entries()].findIndex(
              formsCountEntry => pickDoneFormCount?.substring(0, pickDoneFormCount.lastIndexOf('.')) === formsCountEntry[0]
          );

          let restPart = pickDoneFormCount?.substring(pickDoneFormCount.lastIndexOf('.') + 1); //其他，否

          if (pickDoneFormCount.indexOf("other.") === 0 && theProps.formsCountMap.has("other")) {
            restPart = theProps.formsCountMap.get("other").formCntArr.indexOf(pickDoneFormCount) + "";
          }

          return parseInt(formPartIndex + restPart);
        }, ["asc"]
    )
  }

  if (theProps.batchOperType === BatchOperType.OverWriting) {
    let resultArr = [...theProps.theLijuEntry.pickDoneFormsCountCheckedListMap.entries()].flatMap(theFormPickDoneEntry => {
      let theForm = theFormPickDoneEntry ? theFormPickDoneEntry[0] : undefined;
      let thePickDoneArr = (theFormPickDoneEntry && theFormPickDoneEntry[1]) ? theFormPickDoneEntry[1] : [];
      let toOverWriteFormsCountsArr = theProps.theLijuEntry.batchModifyPendingConfirm.toOverWriteFormsCountsListMap.get(theForm);
      let noMoreOverWriteMode = toOverWriteFormsCountsArr?.noMoreOverWriteMode;
      if (noMoreOverWriteMode) {
        return difference([...toRaw(thePickDoneArr ? thePickDoneArr : [])], ...toRaw(toOverWriteFormsCountsArr ? toOverWriteFormsCountsArr : []));
      } else {
        return toOverWriteFormsCountsArr ? [] : [...toRaw(thePickDoneArr ? thePickDoneArr : [])];
      }
    })

    // resultArr = orderBy(resultArr,
    //     pickDoneFormCount => parseInt([...theProps.formsCountMap.entries()]
    //         .findIndex(
    //             formsCountEntry => pickDoneFormCount?.substring(0, pickDoneFormCount.lastIndexOf('.')) === formsCountEntry[0]
    //         ) + pickDoneFormCount?.substring(pickDoneFormCount.lastIndexOf('.') + 1))
    //     , ["asc"]
    // )

    return orderResultArrByFormsCountMap(resultArr);
  } else if (theProps.batchOperType === BatchOperType.Deleting) {
    if (globelSw?.batchDeletingTheForm.value.trim().length > 0) {
      let resultArr = [...theProps.theLijuEntry.pickDoneFormsCountCheckedListMap.entries()]
          // .filter(theFormPickDoneEntry=>theFormPickDoneEntry[0]!==globelSw?.batchDeletingTheForm.value.trim())
          .flatMap(theFormPickDoneEntry => {
            if (theFormPickDoneEntry[0]?.trim() === globelSw?.batchDeletingTheForm.value.trim()) {
              let theFormsCountMapCheckedListOfForm = theProps.formsCountMap.get(theFormPickDoneEntry[0])?.checkedList;
              return difference([...toRaw(theFormPickDoneEntry[1] ? theFormPickDoneEntry[1] : [])],
                  [...toRaw(theFormsCountMapCheckedListOfForm ? theFormsCountMapCheckedListOfForm : [])]);
            } else {
              return [...toRaw(theFormPickDoneEntry[1] ? theFormPickDoneEntry[1] : [])];
            }
          });
      return orderResultArrByFormsCountMap(resultArr);
    }
  } else {
    // let orderByFormsCountMap = orderBy(,
    //     pickDoneEntry => [...theProps.formsCountMap.entries()]
    //         .findIndex(
    //             formsCountEntry => pickDoneEntry[0] === formsCountEntry[0]
    //         ), ["asc"]);
    // return difference([...theProps.theLijuEntry.pickDoneFormsCountCheckedListMap.values()].flatMap(ele => ele), [...cmptFormsCountTempPickArr.value]);
    let resultArr = [...theProps.theLijuEntry.pickDoneFormsCountCheckedListMap.entries()].flatMap(entry => entry[1]);
    // resultArr = orderBy(resultArr,
    //     pickDoneFormCount => parseInt([...theProps.formsCountMap.entries()]
    //         .findIndex(
    //             formsCountEntry => pickDoneFormCount?.substring(0, pickDoneFormCount.lastIndexOf('.')) === formsCountEntry[0]
    //         ) + pickDoneFormCount?.substring(pickDoneFormCount.lastIndexOf('.') + 1))
    //     , ["asc"]
    // )
    return orderResultArrByFormsCountMap(resultArr);
  }
})

let cmptToAddFormsCountsArr = computed(() => {
  return [...theProps.theLijuEntry.batchModifyPendingConfirm.toAddFormsCountsListMap.values()].flatMap(ele => ele);
})

let cmptToOverWriteFormsCountsArr = computed(() => {
  return difference([...theProps.theLijuEntry.batchModifyPendingConfirm.toOverWriteFormsCountsListMap.values()].flatMap(ele => ele), cmptPickDoneFormsCountArr.value);
})

function pickedDoneTagsDbClickedFunc(e) {
  e.preventDefault();
  pickedDoneClosableSw.value = !pickedDoneClosableSw.value;
}

function closePickedDoneFormCounts(label) {
  remove(theProps.theLijuEntry.pickDoneFormsCountCheckedListMap
      .get(label.substring(0, label.lastIndexOf('.'))), (ele) => ele === label);
}

function closeFormsCountAdding(label) {
  remove(theProps.theLijuEntry.batchModifyPendingConfirm.toAddFormsCountsListMap
      .get(label.substring(0, label.lastIndexOf('.'))), (ele) => ele === label);
}

function closeFormsCountOverWriting(label) {
  let theForm = label.substring(0, label.lastIndexOf('.'));
  let theFormToOverWriteArr = theProps.theLijuEntry.batchModifyPendingConfirm.toOverWriteFormsCountsListMap.get(theForm);
  theFormToOverWriteArr.noMoreOverWriteMode = true;
  remove(theFormToOverWriteArr, (ele) => ele === label);
  if (!theFormToOverWriteArr && theFormToOverWriteArr?.length === 0) {
    theProps.theLijuEntry.batchModifyPendingConfirm.toOverWriteFormsCountsListMap.delete(theForm);
  }
}

// console.log("initiating MarkLijuSingleEntry.vue");
let phraseOWordUsageTopMost = new PhraseOWordUsage();
phraseOWordUsageTopMost.liju = theProps.theLijuEntry.youdaoLiju;
clearAndPushAll(phraseOWordUsageTopMost.pickedPhrasesOWords, theProps.theLijuEntry.pickedPhrasesTopMost);
phraseOWordUsageTopMost.pickedPhrasesOWords.forEach(pickedPhraseOWord => pickedPhraseOWord.liju = theProps.theLijuEntry.youdaoLiju);
phraseOWordUsageTopMost = reactive(phraseOWordUsageTopMost);

let wordUsageTopMost = new PhraseOWordUsage();
wordUsageTopMost.liju = theProps.theLijuEntry.youdaoLiju;
clearAndPushAll(wordUsageTopMost.pickedPhrasesOWords, theProps.theLijuEntry.pickedWordsTopMost);
wordUsageTopMost.pickedPhrasesOWords.forEach(pickedPhraseOWord => pickedPhraseOWord.liju = theProps.theLijuEntry.youdaoLiju);
wordUsageTopMost = reactive(wordUsageTopMost);

// let cptPhraseOWordUsage = computed(()=>{
//   let phraseOWordUsageTopMost = new PhraseOWordUsage();
//   phraseOWordUsageTopMost.liju = theProps.theLijuEntry.youdaoLiju;
//   clearAndPushAll(phraseOWordUsageTopMost.pickedPhrasesOWords,theProps.theLijuEntry.pickedPhrasesOWords);
//   phraseOWordUsageTopMost.pickedPhrasesOWords.forEach(pickedPhraseOWord=>pickedPhraseOWord.liju = theProps.theLijuEntry.youdaoLiju);
//   return phraseOWordUsageTopMost;
// });

let orderedPickedPhrasesOWords = computed(() => {
  // clearAndPushAll()
  // console.log("reordering phrases;")
  if (phraseOWordUsageTopMost.pickedPhrasesOWords.length > 0) {
    return orderBy(phraseOWordUsageTopMost.pickedPhrasesOWords, thePhraseOWord => thePhraseOWord.startWordMark.startIdx);
  } else {
    return [];
  }
})

let orderedPickedWords = computed(() => {
  // console.log("reordering words;")
  if (wordUsageTopMost.pickedPhrasesOWords.length > 0) {
    return orderBy(wordUsageTopMost.pickedPhrasesOWords, thePhraseOWord => thePhraseOWord.startWordMark.startIdx);
  } else {
    return [];
  }
})

function endPhraseOWordIputPicking() {
  let pickedWordsTopMost = [...phraseOWordUsageTopMost.pickedPhrasesOWords].filter(pickedPhraseOWord => pickedPhraseOWord.startWordMark.startIdx === pickedPhraseOWord.endWordMark.startIdx);
  let pickedPhrasesTopMost = difference([...phraseOWordUsageTopMost.pickedPhrasesOWords], pickedWordsTopMost);
  let pickedWordsInWordsModeTopMost = [...wordUsageTopMost.pickedPhrasesOWords].filter(pickedPhraseOWord => pickedPhraseOWord.startWordMark.startIdx === pickedPhraseOWord.endWordMark.startIdx);
  pickedPhrasesTopMost = [...pickedPhrasesTopMost].map(thePhrase => new PhraseOWordUsage.Phrase(thePhrase.startWordMark.clone(), thePhrase.endWordMark.clone(), thePhrase.liju, thePhrase.isValidPhraseOWord));
  let pickedWordsAll = [...pickedWordsTopMost].concat([...pickedWordsInWordsModeTopMost]).map(theWord => new PhraseOWordUsage.Word(theWord.startWordMark.clone(), theWord.endWordMark.clone(), theWord.liju, theWord.isValidPhraseOWord));
  //todo lodash union

  /**
   * //todo 20240308 以下，有问题，已经选择formscounts的words会被清掉
   * 应该用sortedIndexBy之类保留原word，算好idx位置顺序
   *
   * 且没有重新刷focusablePhraseTagRef的索引;
   * 见
   * focusablePhraseTagRef[elThePhrase?.phraseOWordKeyIdxPair] = el;
   */
  // clearAndPushAll(wordUsageTopMost.pickedPhrasesOWords, pickedWordsAll);
  keepIndentifiedSwapIn(phraseOWordUsageTopMost.pickedPhrasesOWords, [...pickedPhrasesTopMost], (inEle, fromEle) => {
    return fromEle.phraseOWordKeyIdxPair === inEle.phraseOWordKeyIdxPair;
  });

  keepIndentifiedSwapIn(wordUsageTopMost.pickedPhrasesOWords, pickedWordsAll, (inEle, fromEle) => {
    return fromEle.phraseOWordKeyIdxPair === inEle.phraseOWordKeyIdxPair;
  });

  // clearAndPushAll(theProps.theLijuEntry.pickedPhrasesTopMost, [...pickedPhrasesTopMost]);
  keepIndentifiedSwapIn(theProps.theLijuEntry.pickedPhrasesTopMost, [...pickedPhrasesTopMost], (inEle, fromEle) => {
    return fromEle.phraseOWordKeyIdxPair === inEle.phraseOWordKeyIdxPair;
  });

  // clearAndPushAll(theProps.theLijuEntry.pickedWordsTopMost, pickedWordsAll);
  keepIndentifiedSwapIn(theProps.theLijuEntry.pickedWordsTopMost, pickedWordsAll, (inEle, fromEle) => {
    return fromEle.phraseOWordKeyIdxPair === inEle.phraseOWordKeyIdxPair;
  });
}

let editingCurrPhrases = ref(0);

// let thePhraseOWordUsage = ref();
function phraseTagsDbclicked(e) {
  e?.preventDefault();
  // if(editingCurrPhrases.value===0){
  if (editingCurrPhrases.value === 0 && globelSw.anyIndividualIsEditing.value === 0) {
    editingCurrPhrases.value++;
    globelSw.anyIndividualIsEditing.value = globelSw.anyIndividualIsEditing.value + 1;
  } else if (editingCurrPhrases.value > 0) {
    editingCurrPhrases.value--;
    globelSw.anyIndividualIsEditing.value = globelSw.anyIndividualIsEditing.value - 1;
  }
}

let editingCurrWords = ref(0);

function wordsTagsDbclicked(e) {
  e?.preventDefault();
  // if(editingCurrWords.value===0){
  if (editingCurrWords.value === 0 && globelSw.anyIndividualIsEditing.value === 0) {
    editingCurrWords.value++;
    globelSw.anyIndividualIsEditing.value = globelSw.anyIndividualIsEditing.value + 1;
  } else if (editingCurrWords.value > 0) {
    editingCurrWords.value--;
    globelSw.anyIndividualIsEditing.value = globelSw.anyIndividualIsEditing.value - 1;
  }
}


function deleteThePhrase(thePhraseOrWord) {
  phraseOWordUsageTopMost.pickedPhrasesOWords.remove(thePhraseOrWord);
  clearAndPushAll(theProps.theLijuEntry.pickedPhrasesTopMost, [...phraseOWordUsageTopMost.pickedPhrasesOWords]);

  if (theProps.theLijuEntry.pickedPhrasesTopMost?.length === 0 && editingCurrPhrases.value > 0) {
    editingCurrPhrases.value--;
    if (globelSw.anyIndividualIsEditing.value && globelSw.anyIndividualIsEditing.value > 0) {
      globelSw.anyIndividualIsEditing.value = globelSw.anyIndividualIsEditing.value - 1;
    }
  }
  // theProps.theLijuEntry.pickedPhrasesOWords.remove(thePhraseOrWord);
  // console.log(thePhraseOrWord);
}

let rootPhraseOWordPickMode = ref(`phrase`);
let keyBoardMoveFocusingCurr = ref(false);

const shortCutKeysEventCenter = inject(globalShortCutKeysEventCenter, undefined);

function focusAndFormsCountsSelectTheFirstPickeWord() {
  if (orderedPickedWords.value.length > 0) {
    let theFirstPickeWord = focusablePhraseTagRef[orderedPickedWords.value[0].phraseOWordKeyIdxPair];
    theFirstPickeWord.keyBoardMoveFocusThis(currFocusingPhasesOWordsRef);
    theFirstPickeWord.currSelectingFormsCounts();
    currFocusingPhasesOWordsRef = theFirstPickeWord;
    shortCutKeysEventCenter?.center.unSubscribe('Alt+q', focusAndFormsCountsSelectTheFirstPickeWord);
  }
}

function keyBoardMoveFocusThis() {
  keyBoardMoveFocusingCurr.value = true;
  // shortCutKeysEventCenter?.center.subscribe(',/,/',toAddPhrases);
  // if(expandingPhrasesAndWordsTags.value){
  //     shortCutKeysEventCenter?.center.subscribe('Alt+q',focusAndFormsCountsSelectTheFirstPickeWord);
  // }
}

watchEffect(() => {
  if (keyBoardMoveFocusingCurr.value && expandingPhrasesAndWordsTags.value) {
    shortCutKeysEventCenter?.center.subscribe('Alt+q', focusAndFormsCountsSelectTheFirstPickeWord);
  }
})

function keyBoardMoveFocusOutThis() {
  keyBoardMoveFocusingCurr.value = false;
  shortCutKeysEventCenter?.center.unSubscribe('Alt+q', focusAndFormsCountsSelectTheFirstPickeWord);
  // shortCutKeysEventCenter?.center.unSubscribe(',/,/',toAddPhrases);
  // if (currPhraseOWordFocusingIdx !== -1) {
  //     cptPhasesOWordsRefs.value[currPhraseOWordFocusingIdx].keyBoardMoveFocusOutThis();
  // }
  currFocusingPhasesOWordsRef?.keyBoardMoveFocusOutThis();
  currFocusingPhasesOWordsRef = null;
  // currPhraseOWordFocusingIdx = -1; //左右移动的置初始
}

// let currPhraseOWordFocusingIdx = -1;
// let prePhasesOWordsRef = null;
let currFocusingPhasesOWordsRef;

function keyBoardMoveLeft() {
  if (!expandingPhrasesAndWordsTags.value) {
    return
  }

  if (cptPhasesOWordsRefs.value.length > 0 && currFocusingPhasesOWordsRef) {
    currFocusingPhasesOWordsRef?.previousPhraseOWordRef?.keyBoardMoveFocusThis(currFocusingPhasesOWordsRef);
    if (!currFocusingPhasesOWordsRef?.previousPhraseOWordRef) {
      currFocusingPhasesOWordsRef.keyBoardMoveFocusOutThis();
      if (expandingPhrasesAndWordsTags.value) {
        shortCutKeysEventCenter?.center.subscribe('Alt+q', focusAndFormsCountsSelectTheFirstPickeWord);
      }
    }
    currFocusingPhasesOWordsRef = currFocusingPhasesOWordsRef?.previousPhraseOWordRef;
  }
  // let allhrasesOWordsLength = phraseOWordUsageTopMost.pickedPhrasesOWords.length+wordUsageTopMost.pickedPhrasesOWords.length;
  // if (cptPhasesOWordsRefs.value.length > 0 && currPhraseOWordFocusingIdx !== -1) {
  //     currPhraseOWordFocusingIdx--;
  //     // console.log("ArrowUp keyed with currEntryFocusingIdx:",currEntryFocusingIdx);
  //     // cptPhasesOWordsRefs.value[currPhraseOWordFocusingIdx + 1].keyBoardMoveFocusOutThis();
  //     prePhasesOWordsRef = cptPhasesOWordsRefs.value[currPhraseOWordFocusingIdx + 1];
  //     if (currPhraseOWordFocusingIdx !== -1) {
  //         cptPhasesOWordsRefs.value[currPhraseOWordFocusingIdx].keyBoardMoveFocusThis(prePhasesOWordsRef);
  //         prePhasesOWordsRef = cptPhasesOWordsRefs.value[currPhraseOWordFocusingIdx];
  //     }else{
  //         prePhasesOWordsRef.keyBoardMoveFocusOutThis();
  //     }
  // }
}

function keyBoardMoveRight() {
  if (!expandingPhrasesAndWordsTags.value) {
    return
  }
  // let allhrasesOWordsLength = phraseOWordUsageTopMost.pickedPhrasesOWords.length+wordUsageTopMost.pickedPhrasesOWords.length;

  if (cptPhasesOWordsRefs.value.length > 0) {
    shortCutKeysEventCenter?.center.unSubscribe('Alt+q', focusAndFormsCountsSelectTheFirstPickeWord);
    if (currFocusingPhasesOWordsRef && currFocusingPhasesOWordsRef?.nextPhraseOWordRef) {
      // console.log("move next");
      // console.log("moving to : ",currFocusingPhasesOWordsRef?.nextPhraseOWordRef?.thuuid)
      currFocusingPhasesOWordsRef?.nextPhraseOWordRef?.keyBoardMoveFocusThis(currFocusingPhasesOWordsRef);
      currFocusingPhasesOWordsRef = currFocusingPhasesOWordsRef?.nextPhraseOWordRef
    } else if (!currFocusingPhasesOWordsRef) {
      // console.log("move first");
      // console.log("moving to : ",cptPhasesOWordsRefs.value[0].thuuid)
      cptPhasesOWordsRefs.value[0].keyBoardMoveFocusThis();
      currFocusingPhasesOWordsRef = cptPhasesOWordsRefs.value[0];
    }
  }
  // if (cptPhasesOWordsRefs.value.length > 0 && currPhraseOWordFocusingIdx !== cptPhasesOWordsRefs.value.length - 1) {
  //     currPhraseOWordFocusingIdx++;
  //     // console.log("ArrowDown keyed with currEntryFocusingIdx:",currEntryFocusingIdx);
  //     if (currPhraseOWordFocusingIdx !== 0) {
  //         // cptPhasesOWordsRefs.value[currPhraseOWordFocusingIdx - 1].keyBoardMoveFocusOutThis();
  //         prePhasesOWordsRef = cptPhasesOWordsRefs.value[currPhraseOWordFocusingIdx - 1];
  //     }
  //     cptPhasesOWordsRefs.value[currPhraseOWordFocusingIdx].keyBoardMoveFocusThis(prePhasesOWordsRef);
  //     prePhasesOWordsRef = cptPhasesOWordsRefs.value[currPhraseOWordFocusingIdx];
  // }
}

defineExpose({
  keyBoardMoveFocusThis,
  keyBoardMoveFocusOutThis,
  keyBoardMoveLeft,
  keyBoardMoveRight,
  toAddPhrases,
  toAddWords
});


let cptPhasesOWordsRefs = computed(() => {
  // console.log("recompute cptPhasesOWordsRefs");
  return [...orderedPickedPhrasesOWords.value].concat([...orderedPickedWords.value]).map(thePhraseOWord =>
      focusablePhraseTagRef[thePhraseOWord.phraseOWordKeyIdxPair]
  );
})

const emits = defineEmits(["iamFocused"]);
let focusablePhraseTagRef = reactive([]);

function refThoseFocusablePhraseTags(el, type) {
  if (el) {
    let elThePhrase = el?.$props?.thePhraseOrWord;
    let theToIdx = sortedIndexBy(focusablePhraseTagRef, el, theEl => {
      // console.log("sorting",theEl?.$props?.theLijuEntry?.youdaoLiju?.eng,theEl?.$props?.theLijuEntry?.aIdx)
      let wordOrPhrase = theEl?.$props?.thePhraseOrWord?.wordOrPhrase;
      if (wordOrPhrase === 'word') {
        return 2e15 + theEl?.$props?.thePhraseOrWord?.startWordMark.startIdx;
      } else if (wordOrPhrase === 'phrase') {
        return 1e15 + theEl?.$props?.thePhraseOrWord?.startWordMark.startIdx;
      }
    });

    let samePhraseOWord =
        focusablePhraseTagRef[theToIdx]?.$props?.thePhraseOrWord.startWordMark.startIdx === elThePhrase?.startWordMark.startIdx &&
        focusablePhraseTagRef[theToIdx]?.$props?.thePhraseOrWord.startWordMark.word === elThePhrase?.startWordMark.word

    let auuid = uuidv4();
    elThePhrase.thuuid = auuid;
    el.thuuid = auuid;


    /**
     * //todo 20240308 如果有一样的词，用新的更新老的？而不是跳过？
     * //flee//v. // version.9 再加caught单词时，重现这个问题。
     * 再按Alt 会报错，因为caught单词没建好 focusablePhraseTagRef[elThePhrase?.phraseOWordKeyIdxPair]
     */
    if (samePhraseOWord) {
      focusablePhraseTagRef.splice(theToIdx, 1, el); //插入一个删除一个->替换
    } else {
      focusablePhraseTagRef.splice(theToIdx, 0, el);//插入
    }
    focusablePhraseTagRef[elThePhrase?.phraseOWordKeyIdxPair] = el;
    if (theToIdx !== 0) {
      focusablePhraseTagRef[theToIdx - 1].nextPhraseOWordRef = el;
    }
    if (focusablePhraseTagRef[theToIdx + 1]) {
      focusablePhraseTagRef[theToIdx + 1].previousPhraseOWordRef = el;
    }
    if (focusablePhraseTagRef[theToIdx + 1]) {
      el.nextPhraseOWordRef = focusablePhraseTagRef[theToIdx + 1];
    }
    el.previousPhraseOWordRef = focusablePhraseTagRef[theToIdx - 1];
  }
}

function wordFormsCountsSelectDoneThen(thePhraseOWordKeyIdxPair) {

  focusablePhraseTagRef[thePhraseOWordKeyIdxPair].nextPhraseOWordRef?.currSelectingFormsCounts();
  if (keyBoardMoveFocusingCurr.value) {
    keyBoardMoveRight();
  }
}

function thePhraseOWordClickedFunc(pickePhraseOWord) {
  // if(keyBoardMoveFocusingCurr.value){
  if (globelSw.readingModeSw.value) {
    focusablePhraseTagRef[pickePhraseOWord.phraseOWordKeyIdxPair]?.keyBoardMoveFocusThis(currFocusingPhasesOWordsRef);
    currFocusingPhasesOWordsRef = focusablePhraseTagRef[pickePhraseOWord.phraseOWordKeyIdxPair];
  }

  // }
}

function toAddPhrases() {
  if (phrasingIt.value) {
    return;
  }
  expandingPhrasesAndWordsTags.value = true;
  rootPhraseOWordPickMode.value = `phrase`;
  phrasingIt.value = true;
  individualFormsCountPickSw.value = false;
  globelSw.anyIndividualIsEditing.value = globelSw.anyIndividualIsEditing.value + 1;
}

function toAddWords() {
  expandingPhrasesAndWordsTags.value = true;
  rootPhraseOWordPickMode.value = `word`;
  phrasingIt.value = true;
  individualFormsCountPickSw.value = false;
  globelSw.anyIndividualIsEditing.value = globelSw.anyIndividualIsEditing.value + 1;
}

watch(expandingPhrasesAndWordsTags,(oldValue,newValue)=>{
  if(!newValue){
    if(editingCurrPhrases.value>0){
      editingCurrPhrases.value = editingCurrPhrases.value-1;
      globelSw.anyIndividualIsEditing.value = globelSw.anyIndividualIsEditing.value - 1;
    }
    if(editingCurrWords.value>0){
      editingCurrWords.value = editingCurrWords.value-1;
      globelSw.anyIndividualIsEditing.value = globelSw.anyIndividualIsEditing.value - 1;
    }
  }
})

onMounted(()=>{
    // console.log("MarkLijuSingleEntry.vue mounted")
})
</script>

<template>

  <!--  {{theLijuEntry.eng}}-->
  <!--  {{theLijuEntry.chi}}-->
  <!--  <br/>-->

  <!--  {{theLijuEntry}}-->
  <!--  <div style="padding-top: 8px" v-show="theLijuEntry.toShow||!maskNotMatched">-->
  <!--    {{keyBoardMoveFocusingCurr}}-->
  <!--  <div :class="{focusable:keyBoardMoveFocusingCurr}" style="margin-top: 8px;padding: 1px 3px;" @mouseenter="focusInFunc" @mouseleave="focusOutFunc" @click="keyBoardMoveFocusingCurr = true;emits(`iamFocused`,theLijuEntry.);">-->
  <div :class="{focusable:keyBoardMoveFocusingCurr}" style="margin-top: 8px;padding: 1px 3px;"

       @mouseenter="focusInFunc" @mouseleave="focusOutFunc"
       @click="(e)=>{if(!keyBoardMoveFocusingCurr&&(globalContextKey1Data?.currEntryFocusingIdxRef.value!==-1||globelSw.readingModeSw.value)){emits(`iamFocused`,theLijuEntry.aIdx);keyBoardMoveFocusThis();}}">

    <div v-if="phrasingIt">
      <el-text>
        <PhraseOWordPickMarkingSingleEntryView
            :pickMode="rootPhraseOWordPickMode"
            :thePhraseOWordUsage="rootPhraseOWordPickMode===`word`?wordUsageTopMost:phraseOWordUsageTopMost">
        </PhraseOWordPickMarkingSingleEntryView>
      </el-text>
    </div>
    <div v-else-if="theLijuEntry.inputPatternMatched">
      <HilightedSentence v-if="theLijuEntry.engHiliParts.toHili">
        <template #prePart>
          <el-text><b>·</b></el-text>
          <span v-for=" (textObj,idx1) in theLijuEntry.engHiliParts.prePartsArr">
    <!--                <el-text v-if="textObj.isBold" tag="b">{{ textObj.text + ' ' }}</el-text>-->
            <!--                <el-text v-else>{{ textObj.text + ' ' }}</el-text>-->
                  <el-text>{{ textObj.text }}</el-text>
                </span>
        </template>
        <template #hilightingPart>
                <span class="group0-hilight">
                    <span v-for=" (textObj,idx1) in theLijuEntry.engHiliParts.hilightPartsArr">
    <!--                <el-text v-if="textObj.isBold" tag="b">{{ textObj.text + ' ' }}</el-text>-->
                      <!--                <el-text v-else>{{ textObj.text + ' ' }}</el-text>-->
                      <el-text>{{ textObj.text }}</el-text>
                    </span>
                </span>
          <!--            <el-text v-for=""></el-text>-->
        </template>
        <template #railPart>
                <span v-for=" (textObj,idx1) in theLijuEntry.engHiliParts.railPartsArr">
    <!--                <el-text v-if="textObj.isBold" tag="b">{{ textObj.text + ' ' }}</el-text>-->
                  <!--                <el-text v-else>{{ textObj.text + ' ' }}</el-text>-->
                  <el-text>{{ textObj.text }}</el-text>
                </span>
        </template>
      </HilightedSentence>
      <div v-else>
        <!--                {{theLijuEntry}}-->
        <el-text>
          <b>·</b>{{ theLijuEntry.eng }}
        </el-text>
      </div>
      <HilightedSentence v-if="theLijuEntry.chiHiliParts.toHili">
        <template #prePart>
                <span v-for=" (textObj,idx1) in theLijuEntry.chiHiliParts.prePartsArr">
    <!--                <el-text v-if="textObj.isBold" tag="b">{{ textObj.text + ' ' }}</el-text>-->
                  <!--                <el-text v-else>{{ textObj.text + ' ' }}</el-text>-->
                  <el-text>{{ textObj.text }}</el-text>
                </span>
        </template>
        <template #hilightingPart>
                <span class="group0-hilight">
                    <span v-for=" (textObj,idx1) in theLijuEntry.chiHiliParts.hilightPartsArr">
    <!--                <el-text v-if="textObj.isBold" tag="b">{{ textObj.text + ' ' }}</el-text>-->
                      <!--                <el-text v-else>{{ textObj.text + ' ' }}</el-text>-->
                      <el-text>{{ textObj.text }}</el-text>
                    </span>
                </span>
          <!--            <el-text v-for=""></el-text>-->
        </template>
        <template #railPart>
                <span v-for=" (textObj,idx1) in theLijuEntry.chiHiliParts.railPartsArr">
    <!--                <el-text v-if="textObj.isBold" tag="b">{{ textObj.text + ' ' }}</el-text>-->
                  <!--                <el-text v-else>{{ textObj.text + ' ' }}</el-text>-->
                  <el-text>{{ textObj.text }}</el-text>
                </span>
        </template>
      </HilightedSentence>
      <div v-else>
        <el-text>
          {{ theLijuEntry.chi }}
        </el-text>
      </div>
    </div>
    <div v-else>
      <PhraseOWordSettledSingleEntryView :theLijuEntry="theLijuEntry"></PhraseOWordSettledSingleEntryView>
    </div>



    <!--    {{pickedDoneClosableSw}}-->

    <!--        {{theProps.theLijuEntry.pickDoneFormCountsArr}}-->
    <div>
      <div style="display: flex">
        <!--                <span v-if="!batchOverWriting">-->
        <span>
                    <PickedDoneFormCountTag v-for="(formCount,idx) in cmptPickDoneFormsCountArr"
                                            :pickedDoneClosableSw="pickedDoneClosableSw"
                                            :label="formCount"
                                            @closeTag="closePickedDoneFormCounts"
                                            :key="idx">
                    </PickedDoneFormCountTag>
                </span>
        <span v-if="theProps.batchOperType===BatchOperType.OverWriting">
<!--                  <BatchOverWritingTags v-model="theModel" :theForm="`v`"></BatchOverWritingTags>-->
                  <FormsCountTempPickTag v-for="(formCount,idx) in cmptToOverWriteFormsCountsArr"
                                         :label="formCount"
                                         @closeTag="closeFormsCountOverWriting"
                                         :key="idx">
                  </FormsCountTempPickTag>
                </span>
        <span v-else-if="theProps.batchOperType===BatchOperType.Adding">
                  <FormsCountTempPickTag v-for="(formCount,idx) in cmptToAddFormsCountsArr"
                                         :label="formCount"
                                         @closeTag="closeFormsCountAdding"
                                         :key="idx">
                  </FormsCountTempPickTag>
                </span>
        <!--                <div class="my-button-cont" v-if="!globelSw.readingModeSw.value&&mouseInCurr&&(phraseOWordUsageTopMost.pickedPhrasesOWords.length>0||wordUsageTopMost.pickedPhrasesOWords.length>0)">-->
<!--        <div class="my-button-cont" v-if="mouseInCurr&&(phraseOWordUsageTopMost.pickedPhrasesOWords.length>0||wordUsageTopMost.pickedPhrasesOWords.length>0)">-->
        <div class="my-button-cont" v-if="(phraseOWordUsageTopMost.pickedPhrasesOWords.length>0||wordUsageTopMost.pickedPhrasesOWords.length>0)">
          <el-button :icon="Expand"
                     v-if="!expandingPhrasesAndWordsTags"
                     @click="expandingPhrasesAndWordsTags = true"
                     type="primary" plain
                     class="smallTheElButton">
          </el-button>
          <el-button :icon="Fold"
                     v-else
                     @click="()=>{
                       // console.log(`2222`);
                         expandingPhrasesAndWordsTags = false;
                         currFocusingPhasesOWordsRef?.keyBoardMoveFocusOutThis();
                         currFocusingPhasesOWordsRef = null;
                     }"
                     type="primary" plain
                     class="smallTheElButton">
          </el-button>
        </div>
        <!--                <el-button @click="orderedPickedPhrasesOWords.forEach(entry=>console.log(entry.thuuid));orderedPickedWords.pickedPhrasesOWords.forEach(entry=>console.log(entry.thuuid));">show</el-button>-->
        <div class="my-button-cont"
             v-if="!globelSw.readingModeSw.value&&!batchFormsCntPickSw&&globelSw.anyIndividualIsEditing.value===0&&mouseInCurr&&formsCountMap.size>0&&!batchIndividual&&!individualFormsCountPickSw&&!pickedDoneClosableSw"
             style="margin-left: 2px">
          <el-button :icon="Edit"
                     @click="individualFormsCountPickSw = true;phrasingIt=false;globelSw.anyIndividualIsEditing.value = globelSw.anyIndividualIsEditing.value+1;"
                     type="primary" plain
                     class="smallTheElButton"></el-button>
        </div>
        <!--                false ||false true ->false ->false-->
        <!--                true ||true true->false ->true /false-->
        <!--                false|| false false ->false -> false-->
        <!--                true || true false->true ->true-->
        <div class="my-button-cont"
             v-if="!globelSw.readingModeSw.value&&!batchFormsCntPickSw&&!phrasingIt&&globelSw.anyIndividualIsEditing.value===0&&mouseInCurr&&!batchIndividual&&theProps.batchOperType===BatchOperType.None">
          <!--            <div>-->
          <el-button :icon="Plus"
                     @click="toAddPhrases"
                     type="primary" plain
                     class="smallTheElButton">Phr.
          </el-button>
        </div>
        <div class="my-button-cont"
             v-if="!globelSw.readingModeSw.value&&!batchFormsCntPickSw&&!phrasingIt&&globelSw.anyIndividualIsEditing.value===0&&mouseInCurr&&!batchIndividual&&theProps.batchOperType===BatchOperType.None">
          <!--            <div>-->
          <el-button :icon="Plus"
                     @click="toAddWords"
                     type="primary" plain
                     class="smallTheElButton">Wd.
          </el-button>
        </div>
        <!--            </div>-->
        <div @dblclick.prevent="pickedDoneTagsDbClickedFunc"
             v-if="cmptPickDoneFormsCountArr?.length>0&&!batchIndividual&&!individualFormsCountPickSw"
             class="dbClickable"></div>
      </div>


      <!--           style="border: 1px solid;display: flow-root;height:25px;width: 200px"></div>-->

    </div>
<!--    <div v-show="phraseOWordUsageTopMost.pickedPhrasesOWords.length>0&&expandingPhrasesAndWordsTags" style="display: flex;flex-wrap: wrap;flex-direction: column">-->
    <div v-show="phraseOWordUsageTopMost.pickedPhrasesOWords.length>0&&expandingPhrasesAndWordsTags" style="display: flex;flex-wrap: wrap;flex-direction: row">
      <!--            <el-tag class="pickedPhraseOWord" v-for="(pickePhraseOWord,idx) in theLijuEntry.phraseOWordUsageTopMost.pickedPhrasesOWords" type="success"><b>{{theLijuEntry.phraseOWordUsageTopMost.eng.substring(pickePhraseOWord.startWordMark.startIdx,pickePhraseOWord.endWordMark.startIdx+pickePhraseOWord.endWordMark.word.length)}}</b></el-tag>-->
      <!--      <el-tag class="pickedPhraseOWord" v-for="(pickePhraseOWord,idx) in orderedPickedPhrasesOWords" type="success">-->
      <!--        <b>{{ pickePhraseOWord.phraseOWordText }}</b></el-tag>-->
      <!--        <div style="display: flex;flex-wrap: wrap;max-width: 90%">-->

      <!--          @endSubPhraseInputPicking="clearAndPushAll(theLijuEntry.pickedPhrasesTopMost,phraseOWordUsageTopMost.pickedPhrasesOWords);"-->

      <!--          @endSubPhraseInputPicking="clearAndPushAll(theLijuEntry.pickedPhrasesTopMost,[...orderedPickedPhrasesOWords]);" //todo 20240310 更细致的替换对应条目Phrase-->
      <!--            :ref="(el)=>refThoseFocusablePhraseTags(el,`phrase`,pickePhraseOWord.xxxx)" //会触发ref对应的函数，造成无限递归？-->
<!--        :style="{zIndex:(600+20*idx)}"-->
      <PhraseTag class="phrase-tag"
                 v-for="(pickePhraseOWord,idx) in orderedPickedPhrasesOWords"
                 :ref="(el)=>refThoseFocusablePhraseTags(el,`phrase`,pickePhraseOWord.xxxx)"
                 :thePhraseOrWord="pickePhraseOWord"
                 :editingCurrPhrases="editingCurrPhrases"
                 :mode="`phrase`"
                 :key="pickePhraseOWord.uniqueId"
                 @endSubPhraseInputPicking="clearAndPushAll(theLijuEntry.pickedPhrasesTopMost,[...orderedPickedPhrasesOWords]);"
                 @click="thePhraseOWordClickedFunc(pickePhraseOWord)"
                 @deletingThisPhrase="deleteThePhrase">
      </PhraseTag>
      <!--        </div>-->

      <span @dblclick.prevent="phraseTagsDbclicked" v-if="orderedPickedPhrasesOWords?.length>0"
            class="dbClickable"></span>
      <!--                <el-tag v-for="(pickePhraseOWord,idx) in theLijuEntry.phraseOWordUsageTopMost.pickedPhrasesOWords" type="success">{{pickePhraseOWord}}</el-tag>-->
    </div>
<!--    <div v-show="wordUsageTopMost.pickedPhrasesOWords.length>0&&expandingPhrasesAndWordsTags" style="display: flex;flex-wrap: wrap;flex-direction: column">-->
    <div v-show="wordUsageTopMost.pickedPhrasesOWords.length>0&&expandingPhrasesAndWordsTags" style="display: flex;flex-wrap: wrap;flex-direction: row">
      <!--            <el-tag class="pickedPhraseOWord" v-for="(pickePhraseOWord,idx) in theLijuEntry.phraseOWordUsageTopMost.pickedPhrasesOWords" type="success"><b>{{theLijuEntry.phraseOWordUsageTopMost.eng.substring(pickePhraseOWord.startWordMark.startIdx,pickePhraseOWord.endWordMark.startIdx+pickePhraseOWord.endWordMark.word.length)}}</b></el-tag>-->
      <!--      <el-tag class="pickedPhraseOWord" v-for="(pickePhraseOWord,idx) in orderedPickedPhrasesOWords" type="success">-->
      <!--        <b>{{ pickePhraseOWord.phraseOWordText }}</b></el-tag>-->
<!--        :style="{zIndex:(100+20*idx)}"-->
      <PhraseTag class="phrase-tag"
                 v-for="(pickedWord,idx) in orderedPickedWords"
                 :ref="(el)=>refThoseFocusablePhraseTags(el,`word`)"
                 :thePhraseOrWord="pickedWord"
                 :colorGroup="`group3`"
                 :editingCurrPhrases="editingCurrWords"
                 :key="pickedWord.uniqueId"
                 @click="thePhraseOWordClickedFunc(pickedWord)"
                 :mode="`word`">
      </PhraseTag>
      <div @dblclick.prevent="wordsTagsDbclicked" v-if="orderedPickedWords?.length>0" class="dbClickable"></div>
      <!--                <el-tag v-for="(pickePhraseOWord,idx) in theLijuEntry.phraseOWordUsageTopMost.pickedPhrasesOWords" type="success">{{pickePhraseOWord}}</el-tag>-->
    </div>

    <!--    pickedDone:{{theLijuEntry.pickDoneFormsCountCheckedListMap}};<br/>-->
    <!--    formsCountCheckedListMap:{{theLijuEntry.formsCountCheckedListMap}}<br/>-->
    <!--    theLijuEntry:{{theLijuEntry.eng}}-->

    <div
        v-if="!batchFormsCntPickSw&&formsCountMap.size>0&&((batchIndividual&&mouseInCurr)||individualFormsCountPickSw)">
      <!--        <div v-if="!batchFormsCntPickSw&&formsCountMap.size>0&&(batchIndividual||individualFormsCountPickSw)">-->
      <FormCheckGroups :formsCountMap="formsCountMap"
                       :isBatchMatch="false"
                       :theLijuEntry="theLijuEntry"
                       :formsCountCheckedListMap="theLijuEntry.formsCountCheckedListMap"
                       @currLijuFormCountsPickDone="currLijuFormCountsPickDoneFunc">
      </FormCheckGroups>
    </div>
  </div>


</template>
<style scoped>
:global(.focusable) {
  border: 1px dashed;
  border-radius: 3px;
  padding: 3px;
}

:deep(.el-button.smallTheElButton) {
  padding: 2px 8px;
  height: var(--common-tag-height);
  margin-top: 1px;
}

:deep(.smallTheElButton+.smallTheElButton) {
  margin-left: 2px;
}

:deep(.my-button-cont+.my-button-cont) {
  margin-left: 5px;
}

.pickedPhraseOWord + .pickedPhraseOWord {
  margin-left: 5px;
}

.phrase-tag + .phrase-tag {
  margin-left: 1px;
}

.dbClickable {
  height: 25px;
  width: 100px;
  background-color: rgba(245, 238, 225, 0.39);
  border-radius: 3px;
}
</style>